package com.brs;

import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;

import com.brs.model.BookItem;
import com.brs.model.Borrower;
import com.brs.model.Card;
import com.brs.model.Library;
import com.brs.model.Manager;

public class Main {
	private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
	private static Library library = genLibrary();

	public static void main(String[] args) {
		Manager manager = getDutyManager();

		System.out.println(library.toString() + " Books: " + library.getTotalBooks());
		System.out.println("Library open now? " + (library.isOpen(new Date()) ? "YES" : "NO"));
		printManagers(library.getManagers());
		printBorrowers(library.getBorrowers());
		printBookItems(library.getBookItems());

		library.addBookItem(new BookItem());
		System.out.println("Books: " + library.getTotalBooks());

		library.removeBookItem(library.getBookItems().get(library.getTotalBooks() - 1));
		System.out.println("Books: " + library.getTotalBooks());

		System.out.println(library.searchBooks("Title1"));
		System.out.println(library.searchBooks(3));

		library.occupySit();
		System.out.println(library.toString());
		library.releaseSit();
		System.out.println(library.toString());

		System.out.println(library.searchBorrower("First Name1"));
		System.out.println(library.searchBorrower(1003));

		manager.issueBook(library.getBorrowers().get(0), library.getBookItems().get(0));
		System.out.println(library.getBorrowers().get(0));
		System.out.println(library.getIssues());

		manager.receiveBook(library.getBookItems().get(0));
		System.out.println(library.getBorrowers().get(0));
		System.out.println(library.getIssues());
	}

	private static Manager getDutyManager() {
		for (Manager manager : library.getManagers()) {
			if (manager.isOnDuty()) {
				return manager;
			}
		}
		return null;
	}

	private static void printBorrowers(ArrayList<Borrower> borrowers) {
		for (Borrower borrower : borrowers) {
			System.out.println(borrower.toString());
		}
	}

	private static void printManagers(ArrayList<Manager> managers) {
		for (Manager manager : managers) {
			System.out.println(manager.toString());
		}
	}

	private static void printBookItems(ArrayList<BookItem> bookItems) {
		for (BookItem bookItem : bookItems) {
			System.out.println(bookItem.toString());
		}
	}

	private static String bytesToHex(byte[] bytes) {
		char[] hexChars = new char[bytes.length * 2];
		for (int j = 0; j < bytes.length; j++) {
			int v = bytes[j] & 0xFF;
			hexChars[j * 2] = hexArray[v >>> 4];
			hexChars[j * 2 + 1] = hexArray[v & 0x0F];
		}
		return new String(hexChars);
	}

	private static ArrayList<Manager> genManagers(int num) {
		ArrayList<Manager> managers = new ArrayList<>();
		Random random = new Random();
		for (int i = 0; i < num; i++) {
			Manager manager = new Manager();
			manager.setSalary(10000 * random.nextFloat());
			manager.setOnDuty(i == num - 1);
			manager.setFirstName("First Name" + Integer.toString(random.nextInt(num)));
			manager.setLastName("Last Name" + Integer.toString(random.nextInt(num)));
			manager.setSex(random.nextInt() % 2 == 0 ? "Male" : "Female");
			manager.setBirthday(new Date(random.nextLong() % 1000 * 3600 * 24 * 365 * 28));
			manager.setAddress("Address" + Integer.toString(random.nextInt(num)));
			manager.setPhoneNumber("PhoneNumber" + Integer.toString(random.nextInt(num)));
			managers.add(manager);
		}
		return managers;
	}

	private static ArrayList<Borrower> genBorrower(int num) {
		ArrayList<Borrower> borrowers = new ArrayList<>();
		Random random = new Random();
		String firstName;
		String lasteName;
		Date date = new Date();
		Borrower borrower = new Borrower();
		for (int i = 0; i < num; i++) {
			date = new Date();
			firstName = "First Name" + Integer.toString(random.nextInt(num));
			lasteName = "Last Name" + Integer.toString(random.nextInt(num));
			borrower.setCard(new Card(1000 + i, firstName + " " + lasteName, date, date, 100 * random.nextFloat()));
			borrower.setMaxIssuedBooks(15);
			borrower.setDailyFee((float) 1.0);
			borrower.setFirstName(firstName);
			borrower.setLastName(lasteName);
			borrower.setSex(random.nextInt() % 2 == 0 ? "Male" : "Female");
			borrower.setBirthday(new Date(random.nextLong() % 1000 * 3600 * 24 * 365 * 28));
			borrower.setAddress("Address" + Integer.toString(random.nextInt(num)));
			borrower.setPhoneNumber("PhoneNumber" + Integer.toString(random.nextInt(num)));
			borrowers.add(borrower);
		}
		return borrowers;
	}

	private static ArrayList<BookItem> genBooks(int num) {
		ArrayList<BookItem> books = new ArrayList<>();
		Random random = new Random();
		try {
			for (int i = 0; i < num; i++) {
				BookItem book = new BookItem();
				book.setBarCode(10000 + i);
				book.setISBN(
						bytesToHex(MessageDigest.getInstance("MD5").digest(ByteBuffer.allocate(4).putInt(i).array())));
				book.setTitle("Title" + Integer.toString(random.nextInt(num)));
				book.setCatagory("Catagory" + Integer.toString(random.nextInt(num)));
				book.setAuthor("Author" + Integer.toString(random.nextInt(num)));
				book.setPublisher("Publisher" + Integer.toString(random.nextInt(num)));
				book.setPublicationDate(new Date(random.nextLong() % 1000 * 3600 * 24 * 365 * 48));
				book.setPages(100 + random.nextInt(1000));
				book.setPrice(100 * random.nextFloat());
				books.add(book);
			}
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return books;
	}

	private static Library genLibrary() {
		Library library = Library.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

		library.setName("BJ Library");
		library.setLocation("2A Jiangtai Road, Chaoyang District Beijing 100016 ​P.R. China");
		library.setTotalSits(155);
		library.setManagers(genManagers(2));
		library.setBorrowers(genBorrower(5));
		library.setBookItems(genBooks(5));
		try {
			library.setOpenTime(sdf.parse("08:00"));
			library.setCloseTime(sdf.parse("17:00"));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return library;
	}

}
